import { Context } from 'egg';
import PlainObject from '../PlainObject';
import RequestFailedError from '../RequestFailedError';

function isJSON(body) {
  if (!body) return false;
  if (typeof body === 'string') return false;
  if (typeof body.pipe === 'function') return false;
  if (Buffer.isBuffer(body)) return false;
  return true;
}

export default () =>
  async function resultWrapper(ctx: Context, next) {
    try {
      await next();
      // 后续中间件执行完成后将响应体转换成 gzip
      const { body } = ctx;
      if (body instanceof PlainObject) {
        ctx.body = body.obj;
      } else if (
        isJSON(body) ||
        body === null ||
        typeof body === 'string' ||
        typeof body === 'number'
      ) {
        ctx.body = {
          errCode: 0,
          errMsg: 'success',
          success: true,
          data: body,
        };
      } else if (body instanceof RequestFailedError) {
        ctx.body = {
          errCode: body.code,
          errMsg: body.message,
          success: false,
        };
      }
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
    } catch (error: any) {
      console.error(error);
      ctx.logger.error(error);
      if (error instanceof RequestFailedError) {
        ctx.body = {
          errCode: error.code,
          errMsg: error.message,
          success: false,
        };
      } else {
        ctx.status = 500;
        ctx.body = {
          errCode: 500,
          errMsg: process.env.NODE_ENV === 'development' ? error.message : 'internal error',
          error: process.env.NODE_ENV === 'development' ? error : undefined,
          success: false,
        };
      }
    }
  };
